using System;

namespace RapidHDL
{
    /// <summary>
    /// Summary description for Adder.
    /// </summary>
    public class Adder : Component
    {
        public NodeVector InputNodesA;
        public NodeVector InputNodesB;
        public NodeVector OutputNodes;
        public NodeVector Carry;

        public Adder(Component poParentComponent, string psName, int piWidthA, int piWidthB, bool pbCarry)
            : base(poParentComponent, psName)
        {
            InputNodesA = this.CreateNodeVector("InA", piWidthA, NodeFlowType.Sink);
            //InputNodesA.ForcedNodeStructure = NodeStructure.Input;
            InputNodesB = this.CreateNodeVector("InB", piWidthB, NodeFlowType.Sink);
            //InputNodesB.ForcedNodeStructure = NodeStructure.Input;
            if (pbCarry)
            {
                Carry = this.CreateNodeVector("Carry", 1, NodeFlowType.Sink);
                //Carry.ForcedNodeStructure = NodeStructure.Input;
            }
            OutputNodes = this.CreateNodeVector("Out", Utility.WidestNodeVector(InputNodesA, InputNodesB) + 1, NodeFlowType.Source);
            OutputNodes.ForcedNodeStructure = NetStructure.Output;
        }

        public override bool InitializeSimulation()
        {
            throw new Exception("Not Implemented yet");
            /*
            SimulationDestabilizeComponent();
            SimulationStabilizeComponent();*/
            return true;
        }

        public override bool TransformStructureToVerilog()
        {
            string sVerilog = "";
            //string sOutputVector = "";
            //string sOutput = "";

            //ComponentVerilog.WriteVerilogText("wire [" +OutputNodes.Width + ":0] sum;",1);
            string sSumLine = "assign " + OutputNodes.Name + " = " + InputNodesA.Name + " + " + InputNodesB.Name;
            if (Carry != null)
                sSumLine += " + " + Carry.Name;
            sSumLine += ";";
            ComponentVerilog.WriteVerilogText(sSumLine, 1);
            return true;
        }

    }
}
